package main

import "fmt"

/*
1、基本介绍
变量(实例)具有多种形态。面向对象的第三大特征，在go中，多态特征是通过接口实现的。
可以按照统一的接口来调用不同的实现，这时接口变量就呈现不同的形态。
2、接口体现多态特征
(1)多态参数
在前面的Usb接口案例，Usb usb，即可以接收手机变量，又可以接收相机变量，就体现了Usb接口 多态
(2)多态数组
演示一个案例：
给Usb数组中，存放Phone结构体和Camera结构体变量，Phone还有一个特有的方法call()
请遍历Usb数组，如果是Phone变量，除了调用Usb接口声明的方法外，还需要调用Phone特有方法call
*/
//声明/定义一个接口
type Usb interface {
	//声明了两个没有实现的方法
	Start()
	Stop()
}
type Phone struct {
	name string
}

//让Phone实现Usb接口的方法
func (p Phone) Start() {
	fmt.Println(p.name, "手机开始工作...")
}
func (p Phone) Stop() {
	fmt.Println(p.name, "手机停止工作...")
}

//让Camera实现Usb接口的方法
type Camera struct {
	name string
}

//让Camera实现Usb接口的方法
func (c Camera) Start() {
	fmt.Println(c.name, "相机开始工作...")
}
func (c Camera) Stop() {
	fmt.Println(c.name, "相机停止工作...")
}

//计算机
type Computer struct {
}

//编写一个方法Working，接收一个Usb接口类型变量
//只要是实现了Usb接口，所谓实现Usb接口，就是指实现了Usb接口声明的所有的方法
func (c Computer) Working(usb Usb) { //usb变量会根据传入的实参，来判断到底是Phone还是Camera，usb接口变量就体现出多态的特点
	//通过usb接口变量来调用Start和Stop方法
	usb.Start()
	usb.Stop()
}
func main() {
	//定义一个Usb接口数组，可以存放Phone和Camera的结构体变量
	//这里就体现出多态数组
	computer := Computer{}
	var usbArr [3]Usb
	usbArr[0] = Phone{"vivo"}
	usbArr[1] = Phone{"小米"}
	usbArr[2] = Camera{"尼康"}
	fmt.Println(usbArr)
	computer.Working(usbArr[0])
	computer.Working(usbArr[1])
	computer.Working(usbArr[2])
}
